package main

import (
	"crypto/md5"
	"fmt"
	"hash/fnv"
	"math"
	"regexp"
	"strings"
	"unicode"
)

// SimpleVectorizer 简单的向量化器（用于演示）
type SimpleVectorizer struct {
	dimension int
}

// NewSimpleVectorizer 创建简单向量化器
func NewSimpleVectorizer(dimension int) *SimpleVectorizer {
	return &SimpleVectorizer{
		dimension: dimension,
	}
}

// Vectorize 将文本向量化
func (v *SimpleVectorizer) Vectorize(text string) []float64 {
	fmt.Printf("🔢 正在向量化文本 (长度: %d 字符)\n", len(text))
	
	// 文本预处理
	processed := v.preprocessText(text)
	
	// 生成向量（使用多种特征组合）
	vector := make([]float64, v.dimension)
	
	// 特征1: 基于字符频率的向量
	charVector := v.generateCharFrequencyVector(processed, v.dimension/4)
	copy(vector[0:], charVector)
	
	// 特征2: 基于词频的向量
	wordVector := v.generateWordFrequencyVector(processed, v.dimension/4)
	copy(vector[v.dimension/4:], wordVector)
	
	// 特征3: 基于n-gram的向量
	ngramVector := v.generateNgramVector(processed, v.dimension/4)
	copy(vector[v.dimension/2:], ngramVector)
	
	// 特征4: 基于语义特征的向量
	semanticVector := v.generateSemanticVector(processed, v.dimension/4)
	copy(vector[3*v.dimension/4:], semanticVector)
	
	// 归一化向量
	v.normalizeVector(vector)
	
	fmt.Printf("✅ 向量化完成，维度: %d\n", len(vector))
	return vector
}

// preprocessText 文本预处理
func (v *SimpleVectorizer) preprocessText(text string) string {
	// 转换为小写
	text = strings.ToLower(text)
	
	// 移除多余的空白字符
	text = regexp.MustCompile(`\s+`).ReplaceAllString(text, " ")
	
	// 保留中文、英文、数字和基本标点
	text = regexp.MustCompile(`[^\p{Han}\p{L}\p{N}\s.,!?;:，。！？；：]`).ReplaceAllString(text, "")
	
	return strings.TrimSpace(text)
}

// generateCharFrequencyVector 基于字符频率生成向量
func (v *SimpleVectorizer) generateCharFrequencyVector(text string, dim int) []float64 {
	vector := make([]float64, dim)
	charCount := make(map[rune]int)
	
	// 统计字符频率
	for _, char := range text {
		if unicode.IsLetter(char) || unicode.IsDigit(char) {
			charCount[char]++
		}
	}
	
	// 将字符映射到向量维度
	for char, count := range charCount {
		hash := fnv.New32a()
		hash.Write([]byte(string(char)))
		index := int(hash.Sum32()) % dim
		vector[index] += float64(count)
	}
	
	return vector
}

// generateWordFrequencyVector 基于词频生成向量
func (v *SimpleVectorizer) generateWordFrequencyVector(text string, dim int) []float64 {
	vector := make([]float64, dim)
	words := v.extractWords(text)
	wordCount := make(map[string]int)
	
	// 统计词频
	for _, word := range words {
		if len(word) >= 2 {
			wordCount[word]++
		}
	}
	
	// 将词映射到向量维度
	for word, count := range wordCount {
		hash := fnv.New32a()
		hash.Write([]byte(word))
		index := int(hash.Sum32()) % dim
		vector[index] += float64(count)
	}
	
	return vector
}

// generateNgramVector 基于n-gram生成向量
func (v *SimpleVectorizer) generateNgramVector(text string, dim int) []float64 {
	vector := make([]float64, dim)
	
	// 2-gram
	for i := 0; i < len(text)-1; i++ {
		ngram := text[i : i+2]
		hash := fnv.New32a()
		hash.Write([]byte(ngram))
		index := int(hash.Sum32()) % dim
		vector[index] += 1.0
	}
	
	// 3-gram
	for i := 0; i < len(text)-2; i++ {
		ngram := text[i : i+3]
		hash := fnv.New32a()
		hash.Write([]byte(ngram))
		index := int(hash.Sum32()) % dim
		vector[index] += 0.5 // 权重稍低
	}
	
	return vector
}

// generateSemanticVector 基于语义特征生成向量
func (v *SimpleVectorizer) generateSemanticVector(text string, dim int) []float64 {
	vector := make([]float64, dim)
	
	// 文档长度特征
	vector[0] = math.Log(float64(len(text) + 1))
	
	// 句子数量特征
	sentences := strings.Split(text, "。")
	if dim > 1 {
		vector[1] = math.Log(float64(len(sentences) + 1))
	}
	
	// 问号数量（疑问句特征）
	if dim > 2 {
		vector[2] = float64(strings.Count(text, "？") + strings.Count(text, "?"))
	}
	
	// 感叹号数量（感叹句特征）
	if dim > 3 {
		vector[3] = float64(strings.Count(text, "！") + strings.Count(text, "!"))
	}
	
	// 数字密度特征
	if dim > 4 {
		digitCount := 0
		for _, char := range text {
			if unicode.IsDigit(char) {
				digitCount++
			}
		}
		vector[4] = float64(digitCount) / float64(len(text)+1)
	}
	
	// 中文字符比例
	if dim > 5 {
		chineseCount := 0
		for _, char := range text {
			if unicode.Is(unicode.Han, char) {
				chineseCount++
			}
		}
		vector[5] = float64(chineseCount) / float64(len(text)+1)
	}
	
	// 填充剩余维度（使用文本哈希）
	if dim > 6 {
		hash := md5.Sum([]byte(text))
		for i := 6; i < dim && i-6 < len(hash); i++ {
			vector[i] = float64(hash[i-6]) / 255.0
		}
	}
	
	return vector
}

// extractWords 提取词语
func (v *SimpleVectorizer) extractWords(text string) []string {
	var words []string
	
	// 按空格和标点分割
	parts := regexp.MustCompile(`[\s.,!?;:，。！？；：]+`).Split(text, -1)
	
	for _, part := range parts {
		part = strings.TrimSpace(part)
		if len(part) == 0 {
			continue
		}
		
		// 对于中文文本，提取2-3字符的组合作为"词"
		runes := []rune(part)
		if len(runes) >= 2 {
			// 添加整个部分
			words = append(words, part)
			
			// 添加2字符组合
			for i := 0; i <= len(runes)-2; i++ {
				words = append(words, string(runes[i:i+2]))
			}
			
			// 添加3字符组合
			for i := 0; i <= len(runes)-3; i++ {
				words = append(words, string(runes[i:i+3]))
			}
		}
	}
	
	return words
}

// normalizeVector 向量归一化
func (v *SimpleVectorizer) normalizeVector(vector []float64) {
	var norm float64
	for _, val := range vector {
		norm += val * val
	}
	norm = math.Sqrt(norm)
	
	if norm > 0 {
		for i := range vector {
			vector[i] /= norm
		}
	}
}